﻿using System;
using System.Resources;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.IO;
using BMproductions.Media.MediaPlayer.WMPPlus;

namespace BMproductions.Media.MediaPlayer.WMPPlus {
	internal class MUIResourceManager: ResourceManager {
		public MUIResourceManager(Type t)
			: base(t) {
			if (t == null) return;
			try {
				var culture = CultureInfo.CurrentUICulture;
				var rs = GetResourceSet(culture, false, true);
				if (rs != null) return;
				rs = LoadMUIResourceSet(t.FullName + "." + culture.Name + ".resources", culture, t.Assembly);
				if (rs != null)
					base.ResourceSets[culture] = rs;
			} catch {
			}
		}

		private static ResourceSet LoadMUIResourceSet(string resource, CultureInfo culture, Assembly assembly) {
			string path = Path.Combine(Path.Combine(
				Environment.GetFolderPath(Environment.SpecialFolder.System),
				culture.Name), Path.GetFileName(assembly.Location) + ".mui");
			if (!File.Exists(path))
				return null;
			var assm = Assembly.LoadFile(path);
			var stream = assm.GetManifestResourceStream(resource);
			return new ResourceSet(stream);
		}

		private static bool LoadMUISatellite(string resource, CultureInfo culture, ResourceManager manager, Assembly assembly) {
			var rs = manager.GetResourceSet(culture, false, true);
			if (rs != null) return true;
			rs = LoadMUIResourceSet(resource, culture, assembly);
			if (rs == null) return false;
			var fi = typeof(ResourceManager).GetField("ResourceSets",
				BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
			if (fi == null)
				return false;
			var sets = (Hashtable)fi.GetValue(manager);
			lock (sets) {
				sets[culture] = rs;
			}
			return true;
		}

		public static void LoadMUIResourceManager(Type type, CultureInfo culture, ResourceManager manager) {
			if (culture == null)
				culture = CultureInfo.CurrentUICulture;
			LoadMUISatellite(type.FullName + "." + culture.Name + ".resources", culture, manager, type.Assembly);
		}
	}
}

namespace System.ComponentModel {
	internal class ComponentResourceManager: MUIResourceManager {
		private CultureInfo _neutralResourcesCulture;
		private Hashtable _resourceSets;

		public ComponentResourceManager(Type t) : base(t) { }

		public void ApplyResources(object value, string objectName) {
			this.ApplyResources(value, objectName, null);
		}

		public virtual void ApplyResources(object value, string objectName, CultureInfo culture) {
			SortedList<string, object> list;
			if (value == null) {
				throw new ArgumentNullException("value");
			}
			if (objectName == null) {
				throw new ArgumentNullException("objectName");
			}
			if (culture == null) {
				culture = CultureInfo.CurrentUICulture;
			}
			if (this._resourceSets == null) {
				ResourceSet set;
				this._resourceSets = new Hashtable();
				list = this.FillResources(culture, out set);
				this._resourceSets[culture] = list;
			} else {
				list = (SortedList<string, object>)this._resourceSets[culture];
				if ((list == null) || (list.Comparer.Equals(StringComparer.OrdinalIgnoreCase) != this.IgnoreCase)) {
					ResourceSet set2;
					list = this.FillResources(culture, out set2);
					this._resourceSets[culture] = list;
				}
			}
			BindingFlags bindingAttr = BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance;
			if (this.IgnoreCase) {
				bindingAttr |= BindingFlags.IgnoreCase;
			}
			bool flag = false;
			if (value is IComponent) {
				ISite site = ((IComponent)value).Site;
				if ((site != null) && site.DesignMode) {
					flag = true;
				}
			}
			foreach (KeyValuePair<string, object> pair in list) {
				int num;
				string key = pair.Key;
				if (key == null) {
					continue;
				}
				if (this.IgnoreCase) {
					if (String.Compare(key, 0, objectName, 0, objectName.Length, StringComparison.OrdinalIgnoreCase) != 0)
						continue;
				} else if (string.CompareOrdinal(key, 0, objectName, 0, objectName.Length) != 0) {
					continue;
				}
				num = objectName.Length;
				if ((key.Length > num) && (key[num] == '.')) {
					string name = key.Substring(num + 1);
					if (flag) {
						PropertyDescriptor descriptor = TypeDescriptor.GetProperties(value).Find(name, this.IgnoreCase);
						if (((descriptor != null) && !descriptor.IsReadOnly) && ((pair.Value == null) || descriptor.PropertyType.IsInstanceOfType(pair.Value))) {
							descriptor.SetValue(value, pair.Value);
						}
						continue;
					}
					PropertyInfo property = null;
					try {
						property = value.GetType().GetProperty(name, bindingAttr);
					} catch (AmbiguousMatchException) {
						Type baseType = value.GetType();
						do {
							property = baseType.GetProperty(name, bindingAttr | BindingFlags.DeclaredOnly);
							baseType = baseType.BaseType;
						}
						while (((property == null) && (baseType != null)) && (baseType != typeof(object)));
					}
					if (((property != null) && property.CanWrite) && ((pair.Value == null) || property.PropertyType.IsInstanceOfType(pair.Value))) {
						property.SetValue(value, pair.Value, null);
					}
				}
			}
		}

		private SortedList<string, object> FillResources(CultureInfo culture, out ResourceSet resourceSet) {
			SortedList<string, object> list;
			ResourceSet set = null;
			if (!culture.Equals(CultureInfo.InvariantCulture) && !culture.Equals(this.NeutralResourcesCulture)) {
				list = this.FillResources(culture.Parent, out set);
			} else if (this.IgnoreCase) {
				list = new SortedList<string, object>(StringComparer.OrdinalIgnoreCase);
			} else {
				list = new SortedList<string, object>(StringComparer.Ordinal);
			}
			resourceSet = this.GetResourceSet(culture, true, true);
			if ((resourceSet != null) && !object.ReferenceEquals(resourceSet, set)) {
				foreach (DictionaryEntry entry in resourceSet) {
					list[(string)entry.Key] = entry.Value;
				}
			}
			return list;
		}

		// Properties
		private CultureInfo NeutralResourcesCulture {
			get {
				if ((this._neutralResourcesCulture == null) && (base.MainAssembly != null)) {
					this._neutralResourcesCulture = ResourceManager.GetNeutralResourcesLanguage(base.MainAssembly);
				}
				return this._neutralResourcesCulture;
			}
		}
	}
}
